package org.ehe.business.step.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.ehe.business.step.domain.BO.StepAnalysisBO;
import org.ehe.business.step.domain.DTO.StepAnalysisDTO;
import org.ehe.business.step.domain.StepAnalysis;
import org.ehe.business.step.domain.VO.StepAnalysisVO;
import org.ehe.business.step.mapper.StepAnalysisMapper;
import org.ehe.business.step.service.StepAnalysisService;
import org.ehe.common.core.service.OssService;
import org.ehe.common.mybatis.core.page.PageQuery;
import org.ehe.common.mybatis.core.page.TableDataInfo;
import org.ehe.common.satoken.utils.LoginHelper;
import org.ehe.system.domain.vo.SysOssVo;
import org.ehe.system.service.ISysOssService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author :zhangnn
 * @className :StepAnalysisServiceImpl
 * @description: TODO
 * @date 2025-08-06 14:06:36
 */
@Slf4j
@Service
public class StepAnalysisServiceImpl extends ServiceImpl<StepAnalysisMapper, StepAnalysis> implements StepAnalysisService {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private ISysOssService ossService;

    @Override
    public StepAnalysisDTO create(StepAnalysisDTO dto) {
        try {
            // 检查文件名是否已存在
//            StepAnalysis existing = this.baseMapper.selectOne(
//                new LambdaQueryWrapper<StepAnalysis>()
//                    .eq(StepAnalysis::getFileName, dto.getFileName())
//            );

//            if (!Objects.isNull(existing)) {
//                throw new RuntimeException("文件名已存在: " + dto.getFileName());
//            }
            StepAnalysis entity = dtoToEntity(dto);
            entity.setCreateBy(LoginHelper.getUsername());
            entity.setTenantId(LoginHelper.getTenantId());
            int result = this.baseMapper.insert(entity);
            if (result > 0) {
                log.info("创建STEP分析结果成功，ID: {}", entity.getId());
                return entityToDto(entity);
            } else {
                throw new RuntimeException("创建失败");
            }
        } catch (Exception e) {
            log.error("创建STEP分析结果失败", e);
            throw new RuntimeException("创建失败: " + e.getMessage());
        }
    }

    @Override
    public StepAnalysisDTO findById(Long id) {
        try {
            StepAnalysis entity = this.baseMapper.selectOne(
                new LambdaQueryWrapper<StepAnalysis>()
                    .eq(StepAnalysis::getId, id)
            );

            if (Objects.isNull(entity)) {
                throw new RuntimeException("记录不存在，ID: " + id);
            }

            return entityToDto(entity);
        } catch (Exception e) {
            log.error("查询STEP分析结果失败，ID: " + id, e);
            throw new RuntimeException("查询失败: " + e.getMessage());
        }
    }

    @Override
    public StepAnalysisDTO findByFileName(String fileName) {
        try {
            StepAnalysis entity = this.baseMapper.selectOne(
                new LambdaQueryWrapper<StepAnalysis>()
                    .eq(StepAnalysis::getFileName, fileName)
            );

            if (Objects.isNull(entity)) {
                throw new RuntimeException("记录不存在，文件名: " + fileName);
            }

            return entityToDto(entity);
        } catch (Exception e) {
            log.error("根据文件名查询STEP分析结果失败: " + fileName, e);
            throw new RuntimeException("查询失败: " + e.getMessage());
        }
    }

    @Override
    public StepAnalysisDTO findByRequestId(String requestId) {
        try {
            StepAnalysis entity = this.baseMapper.selectOne(
                new LambdaQueryWrapper<StepAnalysis>()
                    .eq(StepAnalysis::getRequestId, requestId)
            );

            if (Objects.isNull(entity)) {
                throw new RuntimeException("记录不存在，请求ID: " + requestId);
            }

            return entityToDto(entity);
        } catch (Exception e) {
            log.error("根据请求ID查询STEP分析结果失败: " + requestId, e);
            throw new RuntimeException("查询失败: " + e.getMessage());
        }
    }



    @Override
    public StepAnalysisDTO updateInfo(Long id, StepAnalysisDTO dto) {
        try {
            StepAnalysis existing = this.baseMapper.selectOne(
                new LambdaQueryWrapper<StepAnalysis>()
                    .eq(StepAnalysis::getId, id)
            );

            if (Objects.isNull(existing)) {
                throw new RuntimeException("记录不存在，ID: " + id);
            }

            // 如果修改了文件名，检查是否与其他记录冲突
            if (!existing.getFileName().equals(dto.getFileName())) {
                StepAnalysis conflict = this.baseMapper.selectOne(
                    new LambdaQueryWrapper<StepAnalysis>()
                        .eq(StepAnalysis::getFileName, dto.getFileName())
                        .ne(StepAnalysis::getId, id)
                );

                if (!Objects.isNull(conflict)) {
                    throw new RuntimeException("文件名已存在: " + dto.getFileName());
                }
            }

            // 保留原有的创建时间和ID
            dto.setId(id);
            dto.setCreateBy(existing.getCreateBy());

            StepAnalysis entity = dtoToEntity(dto);

            int result = this.baseMapper.updateById(entity);
            if (result > 0) {
                log.info("更新STEP分析结果成功，ID: {}", id);
                return entityToDto(entity);
            } else {
                throw new RuntimeException("更新失败");
            }
        } catch (Exception e) {
            log.error("更新STEP分析结果失败，ID: " + id, e);
            throw new RuntimeException("更新失败: " + e.getMessage());
        }
    }

    @Override
    public void delete(Long id) {
        try {
            StepAnalysis entity = this.baseMapper.selectOne(
                new LambdaQueryWrapper<StepAnalysis>()
                    .eq(StepAnalysis::getId, id)
            );

            if (Objects.isNull(entity)) {
                throw new RuntimeException("记录不存在，ID: " + id);
            }
            boolean b = this.removeById(id);
            if (b) {
                log.info("删除STEP分析结果成功，ID: {}", id);
            } else {
                throw new RuntimeException("删除失败");
            }
        } catch (Exception e) {
            log.error("删除STEP分析结果失败，ID: " + id, e);
            throw new RuntimeException("删除失败: " + e.getMessage());
        }
    }



    @Override
    public List<StepAnalysisDTO> findAll() {
        try {
            List<StepAnalysis> entities = this.baseMapper.selectList(
                new LambdaQueryWrapper<StepAnalysis>()
            );

            return entities.stream()
                .map(this::entityToDto)
                .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("查询所有STEP分析结果失败", e);
            throw new RuntimeException("查询失败: " + e.getMessage());
        }
    }

    @Override
    public TableDataInfo<StepAnalysisVO> getPage(StepAnalysisBO bo, PageQuery query) {
        try {
            // 构建查询条件
            LambdaQueryWrapper<StepAnalysis> wrapper = new LambdaQueryWrapper<StepAnalysis>();

            // 动态添加查询条件
            if (StringUtils.hasText(bo.getFileName())) {
                wrapper.like(StepAnalysis::getFileName, bo.getFileName());
            }

            if (StringUtils.hasText(bo.getComplexity())) {
                wrapper.eq(StepAnalysis::getComplexity, bo.getComplexity());
            }

            if (StringUtils.hasText(bo.getDifficultyLevel())) {
                wrapper.eq(StepAnalysis::getDifficultyLevel, bo.getDifficultyLevel());
            }

            if (StringUtils.hasText(bo.getRiskLevel())) {
                wrapper.eq(StepAnalysis::getRiskLevel, bo.getRiskLevel());
            }

            if (bo.getAnalysisTimeStart() != null) {
                wrapper.ge(StepAnalysis::getAnalysisTime, bo.getAnalysisTimeStart());
            }

            if (bo.getAnalysisTimeEnd() != null) {
                wrapper.le(StepAnalysis::getAnalysisTime, bo.getAnalysisTimeEnd());
            }

            if (bo.getMinQualityScore() != null) {
                wrapper.ge(StepAnalysis::getQualityScore, bo.getMinQualityScore());
            }

            if (bo.getMaxQualityScore() != null) {
                wrapper.le(StepAnalysis::getQualityScore, bo.getMaxQualityScore());
            }
            wrapper.orderByDesc(StepAnalysis::getCreateTime);

            // 分页查询
            Page<StepAnalysisVO> result = this.baseMapper.selectVoPage(query.build(), wrapper);

            // 转换DTO - 先将VO转为Entity，再转为DTO
            List<StepAnalysisDTO> records = result.getRecords().stream()
                .map(vo -> {
                    // 先将VO转换为实体类
                    StepAnalysis entity = new StepAnalysis();
                    BeanUtils.copyProperties(vo, entity);
                    // 再调用entityToDto转换为DTO
                    return this.entityToDto(entity);
                })
                .collect(Collectors.toList());

            // 构建返回结果
            TableDataInfo<StepAnalysisDTO> tableData = new TableDataInfo<>();
            tableData.setRows(records);
            tableData.setTotal(result.getTotal());

            log.info("分页查询STEP分析结果成功，总数: {}", result.getTotal());
            return TableDataInfo.build(result);
        } catch (Exception e) {
            log.error("分页查询STEP分析结果失败", e);
            throw new RuntimeException("查询失败: " + e.getMessage());
        }
    }


    /**
     * DTO转Entity
     */
    private StepAnalysis dtoToEntity(StepAnalysisDTO dto) {
        try {
            StepAnalysis entity = new StepAnalysis();
            BeanUtils.copyProperties(dto, entity);

            // 转换JSON字段
            if (dto.getGeometricEntities() != null) {
                entity.setGeometricEntities(objectMapper.writeValueAsString(dto.getGeometricEntities()));
            }
            if (dto.getBoundingBox() != null) {
                entity.setBoundingBox(objectMapper.writeValueAsString(dto.getBoundingBox()));
            }
            if (dto.getSurfaceTypes() != null) {
                entity.setSurfaceTypes(objectMapper.writeValueAsString(dto.getSurfaceTypes()));
            }
            if (dto.getMachiningFeatures() != null) {
                entity.setMachiningFeatures(objectMapper.writeValueAsString(dto.getMachiningFeatures()));
            }
            if (dto.getFeatureDetails() != null) {
                entity.setFeatureDetails(objectMapper.writeValueAsString(dto.getFeatureDetails()));
            }
            if (dto.getMaterials() != null) {
                entity.setMaterials(objectMapper.writeValueAsString(dto.getMaterials()));
            }
            if (dto.getMaterialProperties() != null) {
                entity.setMaterialProperties(objectMapper.writeValueAsString(dto.getMaterialProperties()));
            }
            if (dto.getRecommendedProcesses() != null) {
                entity.setRecommendedProcesses(objectMapper.writeValueAsString(dto.getRecommendedProcesses()));
            }
            if (dto.getProcessTimeBreakdown() != null) {
                entity.setProcessTimeBreakdown(objectMapper.writeValueAsString(dto.getProcessTimeBreakdown()));
            }
            if (dto.getCostBreakdown() != null) {
                entity.setCostBreakdown(objectMapper.writeValueAsString(dto.getCostBreakdown()));
            }
            if (dto.getSpecialRequirements() != null) {
                entity.setSpecialRequirements(objectMapper.writeValueAsString(dto.getSpecialRequirements()));
            }
            if (dto.getRequiredEquipment() != null) {
                entity.setRequiredEquipment(objectMapper.writeValueAsString(dto.getRequiredEquipment()));
            }
            if (dto.getQualityIssues() != null) {
                entity.setQualityIssues(objectMapper.writeValueAsString(dto.getQualityIssues()));
            }
            if (dto.getRecommendations() != null) {
                entity.setRecommendations(objectMapper.writeValueAsString(dto.getRecommendations()));
            }
            if (dto.getMetadata() != null) {
                entity.setMetadata(objectMapper.writeValueAsString(dto.getMetadata()));
            }

            if (dto.getResultJson() != null) {
                entity.setResultJson(objectMapper.writeValueAsString(dto.getResultJson()));
            }


            return entity;
        } catch (Exception e) {
            log.error("DTO转Entity失败", e);
            throw new RuntimeException("数据转换失败: " + e.getMessage());
        }
    }

    /**
     * Entity转DTO
     */
    private StepAnalysisDTO entityToDto(StepAnalysis entity) {
        try {
            StepAnalysisDTO dto = new StepAnalysisDTO();
            BeanUtils.copyProperties(entity, dto);

            // 转换JSON字段
            if (StringUtils.hasText(entity.getGeometricEntities())) {
                dto.setGeometricEntities(objectMapper.readValue(entity.getGeometricEntities(), Map.class));
            }
            if (StringUtils.hasText(entity.getBoundingBox())) {
                dto.setBoundingBox(objectMapper.readValue(entity.getBoundingBox(), List.class));
            }
            if (StringUtils.hasText(entity.getSurfaceTypes())) {
                dto.setSurfaceTypes(objectMapper.readValue(entity.getSurfaceTypes(), Map.class));
            }
            if (StringUtils.hasText(entity.getMachiningFeatures())) {
                dto.setMachiningFeatures(objectMapper.readValue(entity.getMachiningFeatures(), List.class));
            }
            if (StringUtils.hasText(entity.getFeatureDetails())) {
                dto.setFeatureDetails(objectMapper.readValue(entity.getFeatureDetails(), Map.class));
            }
            if (StringUtils.hasText(entity.getMaterials())) {
                dto.setMaterials(objectMapper.readValue(entity.getMaterials(), List.class));
            }
            if (StringUtils.hasText(entity.getMaterialProperties())) {
                dto.setMaterialProperties(objectMapper.readValue(entity.getMaterialProperties(), Map.class));
            }
            if (StringUtils.hasText(entity.getRecommendedProcesses())) {
                dto.setRecommendedProcesses(objectMapper.readValue(entity.getRecommendedProcesses(), List.class));
            }
            if (StringUtils.hasText(entity.getProcessTimeBreakdown())) {
                dto.setProcessTimeBreakdown(objectMapper.readValue(entity.getProcessTimeBreakdown(), Map.class));
            }
            if (StringUtils.hasText(entity.getCostBreakdown())) {
                dto.setCostBreakdown(objectMapper.readValue(entity.getCostBreakdown(), Map.class));
            }
            if (StringUtils.hasText(entity.getSpecialRequirements())) {
                dto.setSpecialRequirements(objectMapper.readValue(entity.getSpecialRequirements(), List.class));
            }
            if (StringUtils.hasText(entity.getRequiredEquipment())) {
                dto.setRequiredEquipment(objectMapper.readValue(entity.getRequiredEquipment(), List.class));
            }
            if (StringUtils.hasText(entity.getQualityIssues())) {
                dto.setQualityIssues(objectMapper.readValue(entity.getQualityIssues(), List.class));
            }
            if (StringUtils.hasText(entity.getRecommendations())) {
                dto.setRecommendations(objectMapper.readValue(entity.getRecommendations(), List.class));
            }
            if (StringUtils.hasText(entity.getMetadata())) {
                dto.setMetadata(objectMapper.readValue(entity.getMetadata(), Map.class));
            }
            if (StringUtils.hasText(entity.getOssId())) {
                SysOssVo vo = ossService.getById(Long.valueOf(entity.getOssId()));
                dto.setOssVo(vo);
            }

            return dto;
        } catch (Exception e) {
            log.error("Entity转DTO失败", e);
            throw new RuntimeException("数据转换失败: " + e.getMessage());
        }
    }
}
